package qsh.laputa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import qsh.laputa.entity.Resource;
import qsh.laputa.dao.ResourceMapper;
import qsh.laputa.service.ResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import qsh.laputa.vo.ResourceVO;
import qsh.laputa.vo.TreeVO;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源表 服务实现类
 * </p>
 *
 * @author Qsh
 * @since 2021-02-22
 */
@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {

    /**
     * 根据角色ID，查询该角色所具有的资源
     *
     * @param roleId
     * @return
     */
    @Override
    public List<ResourceVO> listResourcesByRoleId(Long roleId) {
        //查第一级目录
        QueryWrapper<Resource> queryWrapper = Wrappers.query();
        queryWrapper.eq("rr.role_id", roleId).isNull("re.parent_id").orderByAsc("re.sort");
        List<ResourceVO> resourceVOList = baseMapper.listResource(queryWrapper);
        resourceVOList.forEach(r -> {
            Long resourceId = r.getResourceId();
            //查下级菜单
            QueryWrapper<Resource> subQueryWrapper = Wrappers.query();
            subQueryWrapper.eq("rr.role_id", roleId).eq("re.parent_id", resourceId)
                    .orderByAsc("re.sort");
            List<ResourceVO> subResourceVOList = baseMapper.listResource(subQueryWrapper);
            if (CollectionUtils.isNotEmpty(subResourceVOList)) {
                r.setSubs(subResourceVOList);
            }
        });
        return resourceVOList;
    }

    /**
     * 列出资源列表
     *
     * @return
     */
    @Override
    public List<TreeVO> listResource(Long roleId, Integer flag) {
        if (roleId == null) {   //新增
            LambdaQueryWrapper<Resource> wrapper = Wrappers.<Resource>lambdaQuery()
                    .isNull(Resource::getParentId).orderByAsc(Resource::getSort);
            List<Resource> resources = list(wrapper);
            return resources.stream().map(r -> {
                TreeVO treeVO = new TreeVO();
                treeVO.setId(r.getResourceId());
                treeVO.setTitle(r.getResourceName());

                //二级资源
                LambdaQueryWrapper<Resource> subWrapper = Wrappers.<Resource>lambdaQuery()
                        .eq(Resource::getParentId, r.getResourceId()).orderByAsc(Resource::getSort);
                List<Resource> subResources = list(subWrapper);
                if (CollectionUtils.isNotEmpty(subResources)) {
                    List<TreeVO> children = subResources.stream().map(sub -> {
                        TreeVO subTreeVO = new TreeVO();
                        subTreeVO.setId(sub.getResourceId());
                        subTreeVO.setTitle(sub.getResourceName());
                        return subTreeVO;
                    }).collect(Collectors.toList());
                    treeVO.setChildren(children);
                }
                return treeVO;
            }).collect(Collectors.toList());
        } else {    //修改
            QueryWrapper<Resource> wrapper = Wrappers.query();
            wrapper.eq(flag == 1, "rr.role_id", roleId)
                    .isNull("re.parent_id").orderByAsc("re.sort");
            List<TreeVO> treeVOS = baseMapper.listResourcesByRoleId(roleId, wrapper);
            treeVOS.forEach(t -> {
                t.setChecked(false);
                Long id = t.getId();
                QueryWrapper<Resource> subWrapper = Wrappers.query();
                subWrapper.eq(flag == 1, "rr.role_id", roleId)
                        .eq("re.parent_id", id).orderByAsc("re.sort");
                List<TreeVO> children = baseMapper.listResourcesByRoleId(roleId, subWrapper);
                if (CollectionUtils.isNotEmpty(children)) {
                    t.setChildren(children);
                }
            });
            return treeVOS;
        }
    }
}
